import { useState, useCallback, useEffect, useRef } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import { useAppStore } from '@renderer/pages/designer/store/appStore'
import './index.css';

// 上下文菜单组件
const ContextMenu = ({ position, items, onClose }) => {
  if (!position) return null;

  return (
    <div
      className="context-menu"
      style={{
        position: 'absolute',
        left: position.x,
        top: position.y,
        zIndex: 1000
      }}
      onClick={(e) => e.stopPropagation()}
    >
      <ul>
        {items.map((item, index) => (
          <li
            key={index}
            onClick={() => {
              item.action();
              onClose();
            }}
            className="context-menu-item"
          >
            {item.label}
          </li>
        ))}
      </ul>
    </div>
  );
};

// 文件树节点组件
const TreeNode = ({
  node,
  depth,
  onToggle,
  onSelect,
  onMove,
  parentNode,
  onContextMenu,
  onRename,
  isRenaming,
  onRenameComplete
}) => {
  const [{ isDragging }, drag] = useDrag(() => ({
    type: 'NODE',
    item: { ...node, parentId: parentNode?.id },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  }), [node, parentNode]);

  const [{ isOver, canDrop }, drop] = useDrop(() => ({
    accept: 'NODE',
    drop: (draggedNode, monitor) => {
      const didDrop = monitor.didDrop()
      if (didDrop) {
        return
      }
      // 如果拖拽到文件上，使用该文件的父文件夹作为目标
      const targetFolder = node.type === 'file' ? parentNode : node;
      console.log(didDrop, draggedNode, targetFolder, '如果拖拽到文件上，使用该文件的父文件夹作为目标')
      onMove(draggedNode, targetFolder);
    },
    canDrop: (draggedNode) => {
      // 不能拖拽到自身或子文件夹中
      return draggedNode.id !== node.id && (node.type === 'folder' || (node.type === 'file' && parentNode && draggedNode.id !== parentNode.id));
    },
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
      isOverCurrent: monitor.isOver({ shallow: true }),
    }),
  }), [onMove, parentNode, node]);

  const isFolder = node.type === 'folder';
  const isSelected = onSelect?.id === node.id;
  const nameInputRef = useRef(null);

  // 处理重命名完成
  const handleRenameComplete = (e) => {
    if (e.key === 'Enter' || e.type === 'blur') {
      const newName = e.target.value.trim();
      if (newName && newName !== node.name) {
        onRenameComplete(node, newName);
      } else {
        onRenameComplete(node, null);
      }
    }
  };

  // 当进入重命名模式时，自动聚焦输入框
  useEffect(() => {
    if (isRenaming && nameInputRef.current) {
      nameInputRef.current.focus();
      nameInputRef.current.select();
    }
  }, [isRenaming]);

  return (
    <div
      ref={drag}
      style={{ opacity: isDragging ? 0.5 : 1 }}
      className="tree-node"
      onContextMenu={(e) => {
        e.preventDefault();
        e.stopPropagation();
        onContextMenu(e, node);
      }}
    >
      <div
        ref={drop}
        className={`
          ${isFolder ? 'folder' : 'file'}
          ${isSelected ? 'selected' : ''}
          ${isOver && canDrop ? 'drag-over' : ''}
        `}
        onClick={() => {
          if (isRenaming) return;
          if (isFolder) {
            onToggle(node.id);
          } else {
            onSelect(node);
          }
        }}
      >
        <span className="icon">
          {isFolder ? (node.expanded ? '📂' : '📁') : '📄'}
        </span>

        {isRenaming ? (
          <input
            type="text"
            ref={nameInputRef}
            defaultValue={node.name}
            onKeyDown={handleRenameComplete}
            onBlur={handleRenameComplete}
            className="rename-input"
            onClick={(e) => e.stopPropagation()}
            aria-label="name"
          />
        ) : (
          <span className="name">{node.name}</span>
        )}
      </div>

      {isFolder && node.expanded && node.children && (
        <div className="children" style={{ paddingLeft: `${depth * 16}px` }}>
          {node.children.map((child: any) => (
            <TreeNode
              key={child.id}
              node={child}
              depth={depth + 1}
              parentNode={node}
              onToggle={onToggle}
              onSelect={onSelect}
              onMove={onMove}
              onContextMenu={onContextMenu}
              onRename={onRename}
              isRenaming={onRename?.id === child.id}
              onRenameComplete={onRenameComplete}
            />
          ))}
        </div>
      )}
    </div>
  );
};

// 文件资源管理器组件，与本地的资源一一对应
const FileExplorer = () => {

  const fileTree = useAppStore((state) => state.fileTree)
  const setFileTree = useAppStore((state) => state.actions.setFileTree)
  const viewActiveKey = useAppStore((state) => state.viewActiveKey)
  const selectFileAsync = useAppStore((state) => state.actions.selectFileAsync)
  const filteredTree = useAppStore((state) => state.filteredTree)
  const setFilteredTree = useAppStore((state) => state.actions.setFilteredTree)
  const projectPath = useAppStore((state) => state.projectPath)
  const setProjectPath = useAppStore((state) => state.actions.setProjectPath)

  const [searchTerm, setSearchTerm] = useState<string | undefined>();
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [contextMenu, setContextMenu] = useState(null); // 右键菜单
  const [clipboard, setClipboard] = useState(null); // 复制粘贴
  const [renamingNode, setRenamingNode] = useState<any | null>(null); // 重命名节点

  const rootDropRef = useRef(null);

  // 排序函数：文件夹在前，文件在后，按名称排序
  const sortNodes = useCallback((nodes) => {
    return nodes
      .map(node => {
        if (node.children) {
          return {
            ...node,
            children: sortNodes(node.children)
          };
        }
        return node;
      })
      .sort((a, b) => {
        // 文件夹排在文件前面
        if (a.type === 'folder' && b.type !== 'folder') return -1;
        if (a.type !== 'folder' && b.type === 'folder') return 1;

        // 相同类型按名称排序
        return a.name.localeCompare(b.name);
      });
  }, []);

  // 关闭上下文菜单
  const closeContextMenu = useCallback(() => {
    setContextMenu(null);
  }, []);

  // 处理上下文菜单
  const handleContextMenu = useCallback((e, node) => {
    setContextMenu({
      position: { x: e.clientX, y: e.clientY },
      node: node
    });
  }, []);

  // 处理重命名
  const handleRename = useCallback((node) => {
    setRenamingNode(node);
    setContextMenu(null);
  }, []);

  // 完成重命名
  const handleRenameComplete = useCallback(async (node, newName) => {
    if (!newName) {
      setRenamingNode(null);
      return;
    }

    try {
      const oldPath = node.path;

      // 通过IPC重命名文件
      const newPath = await window.electron?.ipcRenderer.invoke('fs:renameFile', oldPath, newName)
      // 更新文件树
      setFileTree(prevTree => {
        const updateNode = (nodes) => {
          return nodes.map(n => {
            if (n.id === node.id) {
              return {
                ...n,
                id: newPath,
                path: newPath,
                name: newName
              };
            }
            if (n.children) {
              return { ...n, children: updateNode(n.children) };
            }
            return n;
          });
        };

        return sortNodes(updateNode(prevTree));
      });

      setRenamingNode(null);
    } catch (err: any) {
      setError(err.message);
      setRenamingNode(null);
    }
  }, [sortNodes]);

  // 新建文件
  const createNewFile = useCallback(async (parentNode) => {
    try {

      // 通过IPC创建文件
      const { filePath, fileName } = await window.electron?.ipcRenderer.invoke('fs:createFile', parentNode.path);

      // 更新文件树
      setFileTree(prevTree => {
        const addFile = (nodes) => {
          return nodes.map(n => {
            if (n.id === parentNode.id) {
              const newFile = {
                id: filePath,
                name: fileName,
                path: filePath,
                type: 'file'
              };
              return {
                ...n,
                children: [...(n.children || []), newFile]
              };
            }
            if (n.children) {
              return { ...n, children: addFile(n.children) };
            }
            return n;
          });
        };

        return sortNodes(addFile(prevTree));
      });

      setContextMenu(null);
    } catch (err: any) {
      setError(err.message);
    }
  }, [sortNodes]);

  // 新建文件夹
  const createNewFolder = useCallback(async (parentNode) => {
    try {

      // 通过IPC创建文件夹
      const { folderPath, folderName } = await window.electron?.ipcRenderer.invoke('fs:createFolder', parentNode.path);

      // 更新文件树
      setFileTree(prevTree => {
        const addFolder = (nodes) => {
          return nodes.map(n => {
            if (n.id === parentNode.id) {
              const newFolder = {
                id: folderPath,
                name: folderName,
                path: folderPath,
                type: 'folder',
                expanded: false,
                children: []
              };
              return {
                ...n,
                children: [...(n.children || []), newFolder]
              };
            }
            if (n.children) {
              return { ...n, children: addFolder(n.children) };
            }
            return n;
          });
        };

        return sortNodes(addFolder(prevTree));
      });

      setContextMenu(null);
    } catch (err: any) {
      setError(err.message);
    }
  }, [sortNodes]);

  // 剪切
  const handleCut = useCallback((node) => {
    setClipboard({ type: 'cut', item: node });
    setContextMenu(null);
  }, []);

  // 复制
  const handleCopy = useCallback((node) => {
    setClipboard({ type: 'copy', item: node });
    setContextMenu(null);
  }, []);

  // 粘贴
  const handlePaste = useCallback(async (targetNode) => {
    if (!clipboard || !targetNode || targetNode.type !== 'folder') return;

    try {
      const sourcePath = clipboard.item.path;
      let targetPath
      if (clipboard.type === 'cut') {
        // 移动文件
        targetPath = await window.electron?.ipcRenderer.invoke('fs:moveFile', sourcePath, targetNode.path, clipboard.item.name);
      } else {
        // 复制文件
        targetPath = await window.electron?.ipcRenderer.invoke('fs:copyFile', sourcePath, targetNode.path, clipboard.item.name);
      }

      // 更新文件树
      setFileTree(prevTree => {
        // 从原位置删除项目（如果是剪切操作）
        if (clipboard.type === 'cut') {
          const removeNode = (nodes) => {
            for (let i = 0; i < nodes.length; i++) {
              if (nodes[i].id === clipboard.item.id) {
                nodes.splice(i, 1);
                return true;
              }
              if (nodes[i].children) {
                if (removeNode(nodes[i].children)) {
                  return true;
                }
              }
            }
            return false;
          };

          removeNode(prevTree);
        }

        // 添加项目到新位置
        const addNode = (nodes) => {
          for (let i = 0; i < nodes.length; i++) {
            const node = nodes[i];

            if (node.id === targetNode.id) {
              if (!node.children) node.children = [];
              node.children.push({
                ...clipboard.item,
                id: targetPath,
                path: targetPath
              });
              return true;
            }

            if (node.children) {
              if (addNode(node.children)) {
                return true;
              }
            }
          }
          return false;
        };

        const newTree = JSON.parse(JSON.stringify(prevTree));
        addNode(newTree);
        return sortNodes(newTree);
      });

      // 如果是剪切操作，清空剪贴板
      if (clipboard.type === 'cut') {
        setClipboard(null);
      }

      setContextMenu(null);
    } catch (err) {
      setError(err.message);
    }
  }, [clipboard, sortNodes]);

  // 删除
  const handleDelete = useCallback(async (node) => {
    try {
      // 确认删除
      const confirm = window.confirm(`确定要删除 "${node.name}" 吗？`);
      if (!confirm) return;

      // 通过IPC删除文件
      await window.electron?.ipcRenderer.invoke('fs:deleteFile', node.path);

      // 更新文件树
      setFileTree(prevTree => {
        const removeNode = (nodes) => {
          for (let i = 0; i < nodes.length; i++) {
            if (nodes[i].id === node.id) {
              nodes.splice(i, 1);
              return true;
            }
            if (nodes[i].children) {
              if (removeNode(nodes[i].children)) {
                return true;
              }
            }
          }
          return false;
        };

        const newTree = JSON.parse(JSON.stringify(prevTree));
        removeNode(newTree);
        return sortNodes(newTree);
      });

      setContextMenu(null);
    } catch (err) {
      setError(err.message);
    }
  }, [sortNodes]);

  // 渲染上下文菜单项
  const getContextMenuItems = useCallback((node) => {
    const items = [];

    if (node.type === 'folder') {
      items.push(
        { label: '新建文件', action: () => createNewFile(node) },
        { label: '新建文件夹', action: () => createNewFolder(node) },
        { label: '---' }
      );
    }

    items.push(
      { label: '剪切', action: () => handleCut(node) },
      { label: '复制', action: () => handleCopy(node) }
    );

    if (clipboard) {
      items.push({ label: '粘贴', action: () => handlePaste(node) });
    }

    items.push(
      { label: '重命名', action: () => handleRename(node) },
      { label: '删除', action: () => handleDelete(node) }
    );

    return items;
  }, [clipboard, createNewFile, createNewFolder, handleCut, handleCopy, handlePaste, handleRename, handleDelete]);

  // 读取目录内容并构建文件树
  const readDirectory = useCallback(async (dirPath: string) => {
    try {
      setIsLoading(true);
      setError('');

      // 通过IPC调用主进程读取目录
      const items = await window.electron?.ipcRenderer.invoke('fs:readDirectory', dirPath) || [];
      // console.log(items, '渲染上下文菜单项')
      const buildTree = (items) => {
        return items.map(item => {
          if (item.type === 'folder') {
            return {
              id: item.path,
              name: item.name,
              path: item.path,
              type: 'folder',
              expanded: false,
              children: []
            };
          } else {
            return {
              id: item.path,
              name: item.name,
              path: item.path,
              type: 'file',
              size: item.size,
              modified: item.modified
            };
          }
        });
      };

      const tree = sortNodes(buildTree(items));
      return tree;
    } catch (err: any) {
      setError(err.message);
      return [];
    } finally {
      setIsLoading(false);
    }
  }, [sortNodes]);

  // 加载文件夹内容
  const loadFolder = useCallback(async (folderPath) => {
    setProjectPath(folderPath);
    const tree = await readDirectory(folderPath);
    setFileTree(tree);
    setFilteredTree(tree);
  }, [readDirectory]);

  // 打开文件夹选择对话框
  const openFolderDialog = useCallback(async () => {
    try {
      const folderPath = await window.electron?.ipcRenderer.invoke('dialog:openDirectory');
      if (folderPath) {
        loadFolder(folderPath);
      }
    } catch (err) {
      setError(`无法打开文件夹: ${err.message}`);
    }
  }, [loadFolder]);

  // 切换文件夹展开状态
  const toggleFolder = useCallback(async (id) => {
    setFileTree(prevTree => {
      const updateTree = (nodes) => {
        return nodes.map(node => {
          if (node.id === id && node.type === 'folder') {
            // 如果文件夹还没有加载内容，则加载
            if (!node.children || node.children.length === 0) {
              readDirectory(node.path).then(children => {
                setFileTree(prev => {
                  const updateChildren = (nodes) => {
                    return nodes.map(n => {
                      if (n.id === id) {
                        return { ...n, children: sortNodes(children) };
                      }
                      if (n.children) {
                        return { ...n, children: updateChildren(n.children) };
                      }
                      return n;
                    });
                  };
                  return sortNodes(updateChildren(prev));
                });
              });
            }
            return { ...node, expanded: !node.expanded };
          }
          if (node.children) {
            return { ...node, children: updateTree(node.children) };
          }
          return node;
        });
      };

      return sortNodes(updateTree(prevTree));
    });
  }, [readDirectory, sortNodes]);

  // 过滤文件树
  const filterTree = useCallback((nodes, term) => {
    if (!term) return nodes;

    return nodes.filter(node => {
      if (node.children) {
        const filteredChildren = filterTree(node.children, term);
        if (filteredChildren.length > 0) {
          return { ...node, children: filteredChildren };
        }
      }
      return node.name.toLowerCase().includes(term.toLowerCase());
    });
  }, []);

  // 移动项目
  const moveNode = useCallback(async (draggedNode, targetFolder) => {
    try {

      // 通过IPC调用主进程移动文件
      const targetPath = await window.electron?.ipcRenderer.invoke('fs:moveFile', draggedNode.path, targetFolder.path, draggedNode.name);

      // 更新文件树
      setFileTree(prevTree => {
        console.log(prevTree, 'prevTree')
        // 从原位置删除项目
        const removeNode = (nodes) => {
          for (let i = 0; i < nodes.length; i++) {
            if (nodes[i].id === draggedNode.id) {
              nodes.splice(i, 1);
              return true;
            }
            if (nodes[i].children) {
              if (removeNode(nodes[i].children)) {
                return true;
              }
            }
          }
          return false;
        };
        // 添加项目到新位置
        const addNode = (nodes) => {
          for (let i = 0; i < nodes.length; i++) {
            const node = nodes[i];

            if (node.id === targetFolder.id) {
              if (!node.children) node.children = [];
              node.children.push({
                ...draggedNode,
                id: targetPath,
                path: targetPath
              });
              return true;
            }

            if (node.children) {
              if (addNode(node.children)) {
                return true;
              }
            }
          }
          return false;
        };

        // 复制树结构
        const newTree = JSON.parse(JSON.stringify(prevTree));

        // 删除原项目
        removeNode(newTree);
        console.log(newTree, 'newTree')
        if (targetFolder.path === projectPath) {
          // 根目录
          newTree.push({
            ...draggedNode,
            id: targetPath,
            path: targetPath
          })
        }
        addNode(newTree);
        return sortNodes(newTree);
      });
    } catch (err: any) {
      setError(err.message);
    }
  }, [sortNodes, projectPath]);

  // 当搜索词变化时更新过滤后的树
  useEffect(() => {
    if (searchTerm) {
      setFilteredTree(sortNodes(filterTree(fileTree, searchTerm)));
    } else {
      setFilteredTree(fileTree);
    }
  }, [searchTerm, fileTree, filterTree, sortNodes]);

  // 初始化：加载用户主目录
  useEffect(() => {
    const init = async () => {
      try {
        const homeDir = await window.electron?.ipcRenderer.invoke('app:getHomeDir');
        loadFolder(homeDir);
      } catch (err) {
        setError(`无法获取主目录: ${err.message}`);
      }
    };
    init();
  }, [loadFolder]);

  // 修复：允许拖拽到根目录
  const [{ isOver: isRootOver, canDrop: canRootDrop }, rootDrop] = useDrop(() => ({
    accept: 'NODE',
    drop: (draggedNode, monitor) => {
      const didDrop = monitor.didDrop()
      if (didDrop) {
        return
      }
      // 创建代表当前文件夹的节点
      const targetFolder = {
        id: projectPath,
        path: projectPath,
        type: 'folder'
      };
      console.log(draggedNode, targetFolder, didDrop, '修复：允许拖拽到根目录')
      moveNode(draggedNode, targetFolder);
    },
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
      isOverCurrent: monitor.isOver({ shallow: true }),
    }),
  }), [projectPath, moveNode]);

  // 合并拖拽引用
  useEffect(() => {
    rootDrop(rootDropRef.current);
  }, [rootDrop]);

  return (
    <div className="file-explorer-container h-full overflow-auto" onClick={closeContextMenu}>
      {/* 上下文菜单 */}
      {contextMenu && (
        <ContextMenu
          position={contextMenu.position}
          items={getContextMenuItems(contextMenu.node)}
          onClose={closeContextMenu}
        />
      )}
      {/* 文件资源管理器内容 */}
      <div className="explorer-header">
        <div className="header-title">
          <span className="icon">📁</span>
          <h3>文件资源管理器</h3>
        </div>
        <div className="path-display">
          <span className="path-icon">📍</span>
          <span className="path-text">{projectPath}</span>
        </div>
        <div className="actions">
          <button type='button' className="open-folder-btn" onClick={openFolderDialog}>
            打开文件夹
          </button>
        </div>
        <div className="search-box">
          <input
            type="text"
            placeholder="搜索文件..."
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
          />
          <span className="search-icon">🔍</span>
        </div>
      </div>
      <div
        ref={rootDropRef}
        className={`file-tree ${isRootOver && canRootDrop ? 'drag-over-root' : ''}`}
        onClick={closeContextMenu}
      >
        {isLoading ? (
          <div className="loading-indicator">
            <div className="spinner"></div>
            <p>加载中...</p>
          </div>
        ) : error ? (
          <div className="error-message">
            <span className="error-icon">⚠️</span>
            <p>{error}</p>
          </div>
        ) : filteredTree.length > 0 ? (
          filteredTree.map(node => (
            <TreeNode
              key={node.id}
              node={node}
              depth={0}
              parentNode={null}
              onToggle={toggleFolder}
              onSelect={selectFileAsync}
              onMove={moveNode}
              onContextMenu={handleContextMenu}
              onRename={renamingNode}
              isRenaming={renamingNode?.id === node.id}
              onRenameComplete={handleRenameComplete}
            />
          ))
        ) : (
          <div className="no-results">
            <p>文件夹为空</p>
          </div>
        )}
      </div>
      <div className="selected-file-info">
        {viewActiveKey ? (
          <p className=' break-all break-words'>{viewActiveKey}</p>
        ) : (
          <p>请选择一个文件</p>
        )}
      </div>
      {/* 剪贴板状态指示器 */}
      {clipboard && (
        <div className="clipboard-indicator">
          <span className="clipboard-icon">📋</span>
          <span>{clipboard.type === 'cut' ? '已剪切: ' : '已复制: '}{clipboard.item.name}</span>
        </div>
      )}
    </div>
  );
};

// 辅助函数：格式化文件大小
function formatFileSize(bytes?: number) {
  if (!bytes) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

// 辅助函数：格式化日期
function formatDate(dateString?: string) {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleString();
}



export default FileExplorer;
